//
//  Types.swift
//  SitPosition
//
//  Created by apple on 2019/1/6.
//  Copyright © 2019 apple. All rights reserved.
//

import Foundation

public typealias ErrorCallback = (Error?) -> Void

public typealias VoidCallback = () -> Void

public typealias DataParamCallback = (Data?) -> Void


/**
 * 支付类型
 */
enum PurchaseType: Int {
    case alipay=1
    case weichat=2
}


/**
 * 服务端返回的错误包体结构
 */
public struct ServerErrorBody : Codable {
    let code: String?
    let message: String?
    
    enum CodingKeys : String, CodingKey {
        case code
        case message
    }
    
    public init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        if let sCode = try? container.decode(String.self, forKey: .code) {
            self.code = sCode
        } else if let iCode = try? container.decode(Int.self, forKey: .code) {
            self.code = String(iCode)
        } else {
            self.code = nil
        }
        message = try? container.decode(String.self, forKey: .message)
    }
}

/**
 * App内部错误类型
 */
public enum SPError : Error, CustomStringConvertible, CustomDebugStringConvertible {
    case unknwon
    case invalidParams
    case unexpectedServerResponse
    case networkError(body: ServerErrorBody)
    case dbError
    
    init?(data: Data) {
        do {
            let decoder: JSONDecoder = JSONDecoder()
            let body: ServerErrorBody = try decoder.decode(ServerErrorBody.self, from: data)
            self = SPError.networkError(body: body)
        } catch {
            return nil
        }
    }
    
    // Token是否失效？
    var isTokenExpiredError: Bool {
        if case let SPError.networkError(body) = self,
            let code = body.code,
            code == "204010" {
            return true
        } else {
            return false
        }
    }
    
    public var description: String {
        switch self {
        case .unknwon: return Strings.errUnknown
        case .invalidParams: return Strings.errInvalidParams
        case .unexpectedServerResponse: return Strings.unexpectedResponseError
        case .networkError: return Strings.networkError
        case .dbError: return Strings.errDBOperation
        }
    }
    
    public var debugDescription: String {
        return self.description
    }
    
    public var localizedDescription: String {
        return description
    }
}


/**
 * Error扩展接口
 */
extension Error {
    
    // 返回网络错误消息体
    var networkErrorMessage: String? {
        if let spe = self as? SPError,
            case let SPError.networkError(body) = spe {
            return body.message
        } else {
            return nil
        }
    }
}


/**
 * CGFloat扩展
 */
extension CGFloat {
    
    // 角度 -> 弧度
    var radians: CGFloat {
        return CGFloat(Double.pi) * (self/180)
    }
}


/**
 * 以秒为单位的时间扩展
 */
extension TimeInterval {
    
    // 将秒转换为格式化的字符串
    var formatedTimeString: String {
        let h: Int = Int(self)/3600
        let m: Int = (Int(self) % 3600)/60
        let s: Int = Int(self)-h*3600-m*60
        return String(format: "%02d:%02d:%02d", h, m, s)
    }
}

/**
 * UIColor
 */
extension UIColor {
    
    // RGB
    class func rgb(_ r: Int, _ g: Int, _ b: Int) -> UIColor{
        return UIColor(red: CGFloat(r) / 255.0,
                       green: CGFloat(g) / 255.0,
                       blue: CGFloat(b) / 255.0,
                       alpha: 1)
    }
    
    // RGBA
    class func rgb(_ r: Int, _ g: Int, _ b: Int, a: CGFloat) -> UIColor{
        return UIColor(red: CGFloat(r) / 255.0,
                       green: CGFloat(g) / 255.0,
                       blue: CGFloat(b) / 255.0,
                       alpha: a)
    }
}


/**
 * UIImage
 */
extension UIImage {
    
    // 调整Image尺寸（单位：像素）
    func resize(to pixelSize: CGSize) -> UIImage {
        UIGraphicsBeginImageContextWithOptions(pixelSize, true, 1.0)
        draw(in: CGRect(x: 0, y: 0, width: pixelSize.width, height: pixelSize.height))
        let resizedImage = UIGraphicsGetImageFromCurrentImageContext()!
        UIGraphicsEndImageContext()
        return resizedImage
    }
}

/**
 * CMSampleBuffer
 */

extension CMSampleBuffer {
    
    // 转换为UIImage
    // @orientation：旋转方向
    // @cropRect：裁剪区域
    func stillImage(_ orientation: CGImagePropertyOrientation = .leftMirrored, cropRect: CGRect = .zero) -> UIImage? {
        guard let imageBuffer = CMSampleBufferGetImageBuffer(self) else {
            return nil
        }
        let context: CIContext = CIContext()
        let ciImage: CIImage
        if cropRect == CGRect.zero {
            ciImage = CIImage(cvImageBuffer: imageBuffer)
                .oriented(orientation)
        } else {
            ciImage = CIImage(cvImageBuffer: imageBuffer)
                .oriented(orientation)
                .cropped(to: cropRect)
        }
        guard let cgImage: CGImage = context.createCGImage(ciImage, from: ciImage.extent) else {
            return nil
        }
        return UIImage(cgImage: cgImage)
    }
}


/**
 * Bundle
 */
extension Bundle {
    
    // 主版本号
    var releaseVersionNumber: String? {
        return infoDictionary?["CFBundleShortVersionString"] as? String
    }
    
    // Build版本号
    var buildVersionNumber: String? {
        return infoDictionary?["CFBundleVersion"] as? String
    }
}
